// Copyright  2012 Petr TALLA. [petr.talla@gmail.com]
// This file is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY;  without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
// [http://www.gnu.org/copyleft/lesser.html]
//=============================================================================

package tc.crase.cmds;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import tc.common.registry.RegistrySys;
import tc.common.utility.GrView;
import tc.common.utility.Pair;
import tc.common.utility.TcCmd;
import tc.common.utility.TcDisplayTransf;

import tc.crase.db.XattrLNK;
import tc.crase.db.Xdb;
import tc.crase.meta.LinkEstimate;
import tc.crase.sys.XdbEx;
import tc.crase.sys.XobjectEx;

public class CmdLink extends CmdEx  implements ActionListener {
	JLabel object1Label;
	
	JLabel object2Label;
		
	JTextField nameText1;
	JTextField nameText2;
	
	ButtonGroup radioGroup;
	JPanel radioList = new JPanel();
	
	JButton cleanButton;
	JButton createButton;
	
	public XobjectEx xoFirst() {
		if (Selection.selset.size() < 1) return null;
		return (XobjectEx)Selection.selset.get(0);
	}
	
	public XobjectEx xoSecond() {
		if (Selection.selset.size() < 2) return null;
		return (XobjectEx)Selection.selset.get(1);
	}
	
	public CmdLink () {
	}
	
	private void update() {
		object1Label.setText("<html><b>not selected</b></html>");
		object2Label.setText("<html><b>not selected</b></html>");
		
		if (xoFirst() != null)  {
			XobjectEx obj1 = xoFirst();
			object1Label.setText("<html>" + obj1.formatTypes() + ": <b>" + obj1.getName() + "</b></html>");
		}
		
		if (xoSecond() != null)  {
			XobjectEx obj2 = xoSecond();
			object2Label.setText("<html>" + obj2.formatTypes() + ": <b>" + obj2.getName() + "</b></html>");
		}
		
		if ( (xoFirst() != null) || (xoSecond() !=null )) {
			cleanButton.setEnabled(true);
		}
		else
		{	cleanButton.setEnabled(false);
		}
		
		if ( (xoFirst() == null) || (xoSecond() ==null )) {
			for (int i = 0; i < radioList.getComponentCount(); i++) {
				radioGroup.remove((AbstractButton) radioList.getComponent(i));
			}
			
			radioList.removeAll();

			nameText1.setText("");
			nameText2.setText("");
		}
		
		updateText();
		
		if (xoFirst() == null) setHint("Select first object.");
		else if (xoSecond() == null) setHint("Select secondObject.");
		else setHint("Click button <b>Create</b> to create link.");  

	}
	
	public void updateText() {
		if ( (xoFirst() == null) || (xoSecond() == null) ) {
			nameText1.setText("");
			nameText2.setText("");
			return;
		}
		
		JRadioButton buttoni = null;
		
		for (int i = 0; i < radioList.getComponentCount(); i++) {
			buttoni = (JRadioButton)radioList.getComponent(i);
			if (buttoni.isSelected()) break; 
		}

		//Xdb db = xoFirst().getDb();
		XdbEx dbex = xoFirst().getDb();
		
		//Vector<LinkEstimate> estimates = dbex.metadata.estimates;
			
		Vector<Pair<LinkEstimate, Boolean>> matches = new Vector<Pair<LinkEstimate, Boolean>>(); 
		dbex.metadata.searchEstimates (xoFirst().getType(), xoSecond().getType(), matches);
		
		if ( buttoni != null ) {
					

			if (matches.size() > 1) {
				for ( int i = 0; i < matches.size(); i++ ) {
					Pair<LinkEstimate, Boolean> matchi = matches.get(i);
					boolean reverse = matchi.second;
					String texti = buttoni.getText();
					String namei = matchi.first.getName(reverse);
					if ( texti.equals(namei) == false) continue; 
					
					nameText1.setText( matchi.first.getLinkName1(reverse));
					nameText2.setText( matchi.first.getLinkName2(reverse));
					
					return;
				}
			}
		}
		else if (matches.size() > 0) {
			Pair<LinkEstimate, Boolean> match = matches.get(0);
			boolean reverse = match.second;
			nameText1.setText(match.first.getLinkName1(reverse));
			nameText2.setText(match.first.getLinkName2(reverse));
			
			return;
		}

		
		nameText1.setText("relates");
		nameText2.setText("relates");
	}
	
	public void initializeDialog() {
		super.initializeDialog();
		setLabel("Link");
		setHint("Enter point.");
		
		Selection.objectsAllowed = true;
		
		object1Label = new JLabel();
		
		nameText1  = new JTextField();
		nameText1.setMaximumSize(new Dimension((100*SIDEBAR_WIDTH)/80,24));
		
		radioGroup = new ButtonGroup();
		radioList = new JPanel();
				
		nameText2 = new JTextField();
		nameText2.setMaximumSize(new Dimension((100*SIDEBAR_WIDTH)/80,24));
		
		object2Label = new JLabel();
		
		cleanButton = new JButton("Clean");
		cleanButton.addActionListener(this);
		cleanButton.setActionCommand("clean");
		cleanButton.setMaximumSize(new Dimension(80,24));
		cleanButton.setPreferredSize(new Dimension(80,24));

		createButton = new JButton("Create");
		createButton.addActionListener(this);
		createButton.setActionCommand("create");
		createButton.setPreferredSize(new Dimension(SIDEBAR_WIDTH,32));
		createButton.setMaximumSize(new Dimension(SIDEBAR_WIDTH,32));

		dialog.add(object1Label);
		dialog.add(Box.createRigidArea(new Dimension(0,3)));
		Box box = Box.createHorizontalBox();
		dialog.add(box);
		box.add(nameText1);
				
		dialog.add(Box.createRigidArea(new Dimension(0,10)));
				
		dialog.add(object2Label);
		dialog.add(Box.createRigidArea(new Dimension(0,3)));
		box = Box.createHorizontalBox();
		dialog.add(box);
		box.add(nameText2);
		
		dialog.add(Box.createRigidArea(new Dimension(0,20)));
		dialog.add(cleanButton);
		dialog.add(Box.createRigidArea(new Dimension(0,50)));
		dialog.add(createButton);
		
		dialog.add(radioList);
						
		finalizeDialog();
		
		update();
		
		Selection.objectsAllowed = true;
	}
	
	public void enterSelected(Point pt, GrView view, Object object) {
		if (xoFirst() == null) {
			if (object instanceof XobjectEx == false) return;
			RegistrySys.registry.lock(); {
				Selection.add((XobjectEx)object);
			} RegistrySys.registry.unlock();
		}
		else if (xoSecond() == null) {
			if (object instanceof XobjectEx == false) return;
			XobjectEx second = (XobjectEx)object; 
			
			Xdb db = xoFirst().getDb();
			/*if (db != second.getDb()) {
				return;
			}*/
			
			RegistrySys.registry.lock(); {
				Selection.add(second);
			} RegistrySys.registry.unlock();	
			
			String linkName1 = "relates";
			String linkName2 = "relates";
			
			if (db instanceof XdbEx ) {
				XdbEx dbex = (XdbEx)db;
				Vector<LinkEstimate> estimates = dbex.metadata.estimates;
				
				Vector<Pair<LinkEstimate, Boolean>> matches = new Vector<Pair<LinkEstimate, Boolean>>(); 
				dbex.metadata.searchEstimates (xoFirst().getType(), xoSecond().getType(), matches);
				
				if (matches.size() > 1) {
					for ( int i = 0; i < matches.size(); i++ ) {
						Pair<LinkEstimate, Boolean> matchi = matches.get(i);
						boolean reverse = matchi.second;
						String name = matchi.first.getName(reverse); 
						
						JRadioButton infoRadio = new JRadioButton(name);
						infoRadio.addActionListener(this);
						infoRadio.setActionCommand(name);
						infoRadio.setAlignmentX(0.0f);
						infoRadio.setPreferredSize(new Dimension(TcCmd.SIDEBAR_WIDTH,24));
						infoRadio.setMaximumSize(new Dimension(TcCmd.SIDEBAR_WIDTH,24));
						
						if (i == 0) infoRadio.setSelected(true); 
						
						
						radioGroup.add(infoRadio);
						radioList.add(infoRadio);
					}
				}
			}
			
			nameText1.setText(linkName1);
			nameText2.setText(linkName2);
		}
		
		update();
	}
	
	public void enterReset(GrView view) {
	}
	public void enterMove(Point pt, GrView view)  {
	}
	
	private void draw(Graphics g, TcDisplayTransf transf, Color background)
	{
	}
	
	public void actionPerformed(ActionEvent e) {
		if ("create".equals(e.getActionCommand())) {
			RegistrySys.registry.lock(); {
				XattrLNK.connect(nameText1.getText(), xoFirst(), nameText2.getText(), xoSecond());
				Selection.clean();
			} RegistrySys.registry.unlock();
			update();
		}
		else if ("clean".equals(e.getActionCommand())) {
			RegistrySys.registry.lock(); {
				Selection.clean();
			} RegistrySys.registry.unlock();	
			update();
		}
		else { //radio selection clicked
			update();
		}
	}
}

